import urlParser from './util/urlParser.js';
import settings from './util/settings/settings.js';
import myglobal from '../myglobal'
const log=window.__electronLog;
log.info('Log from the renderer process');
const path = window.require('path');
const ipc = window.require('electron').ipcRenderer
var topHeight = 600;
var webviewMinZoom = 0.5;
var webviewMaxZoom = 3.0;

function scrollOnLoad(tabid, scrollPosition) {
  const listener = function (eTabId) {
    if (eTabId === tabid) {
      // the scrollable content may not be available until some time after the load event, so attempt scrolling several times
      // but stop once we've successfully scrolled once so we don't overwrite user scroll attempts that happen later
      for (let i = 0; i < 3; i++) {
        var done = false;
        setTimeout(function () {
          if (!done) {
            webviews.callAsync(
              tabid,
              'executeJavaScript',
              `
            (function() {
              window.scrollTo(0, ${scrollPosition})
              return window.scrollY === ${scrollPosition}
            })()
            `,
              function (err, completed) {
                if (!err && completed) {
                  done = true;
                }
              }
            );
          }
        }, 750 * i);
      }
      webviews.unbindEvent('did-finish-load', listener);
    }
  };
  webviews.bindEvent('did-finish-load', listener);
}

function setAudioMutedOnCreate(tabid, muted) {
  console.log("setAudioMutedOnCreate")
  console.log(tabid)
  console.log(muted)
  const listener = function () {
    webviews.callAsync(tabid, 'setAudioMuted', muted);
    webviews.unbindEvent('did-navigate', listener);
  };
  webviews.bindEvent('did-navigate', listener);
}

const webviews = {
  viewList: [], // [tabid]
  viewFullscreenMap: {}, // tabid, isFullscreen
  selectedId: null,
  placeholderRequests: [],
  asyncCallbacks: {},
  internalPages: {
    error: urlParser.getFileURL(
      myglobal['home'] + '/pages/error/index.html'
    ),
  },
  events: [],
  IPCEvents: [],
  zoomWebviewBy: function (tabid, amt) {
    webviews.callAsync(tabid, 'zoomFactor', function (err, oldFactor) {
      console.log('call 2');
      console.log(oldFactor);
      webviews.callAsync(
        tabid,
        'zoomFactor',
        Math.min(webviewMaxZoom, Math.max(webviewMinZoom, oldFactor + amt))
      );
    });
  },
  zoomWebviewIn: function (tabid) {
    return this.zoomWebviewBy(tabid, 0.2);
  },
  zoomWebviewOut: function (tabid) {
    return this.zoomWebviewBy(tabid, -0.2);
  },
  resetWebviewZoom: function (tabid) {
    webviews.callAsync(tabid, 'zoomFactor', 1.0);
  },
  bindEvent: function (event, fn) {
    webviews.events.push({
      event: event,
      fn: fn,
    });
  },
  unbindEvent: function (event, fn) {
    for (var i = 0; i < webviews.events.length; i++) {
      if (webviews.events[i].event === event && webviews.events[i].fn === fn) {
        webviews.events.splice(i, 1);
        i--;
      }
    }
  },
  openURL: (tabid, url, event) => {
    webviews.update(tabid, url);//
    webviews.focus();
  },
  emitEvent: function (event, viewId, args) {
    if (!webviews.viewList.includes(viewId)) {
      // the view could have been destroyed between when the event was occured and when it was recieved in the UI process, see https://github.com/minbrowser/min/issues/604#issuecomment-419653437
      return;
    }
    webviews.events.forEach(function (ev) {
      if (ev.event === event) {
        ev.fn.apply(this, [viewId].concat(args));
      }
    });
  },
  bindIPC: function (name, fn) {
    webviews.IPCEvents.push({
      name: name,
      fn: fn,
    });
  },
  viewMargins: [0, 0, 0, 0], // top, right, bottom, left
  adjustMargin: function (margins) {
    for (var i = 0; i < margins.length; i++) {
      webviews.viewMargins[i] += margins[i];
    }
    webviews.resize();
  },
  getViewBounds2: function (height) {
    topHeight = Math.round(height);
    if (webviews.viewFullscreenMap[webviews.selectedId]) {
      return {
        x: 0,
        y: 0,
        width: window.innerWidth,
        height: window.innerHeight,
      };
    } else {
      var navbarHeight = topHeight;
      const viewMargins = webviews.viewMargins;
      let x=0 + Math.round(viewMargins[3])
      let y=0 + Math.round(viewMargins[0]) + navbarHeight
      let width= window.innerWidth - Math.round(viewMargins[1] + viewMargins[3])
      let height=window.innerHeight -Math.round(viewMargins[0] + viewMargins[2]) - navbarHeight
      if (isNaN(y) || y==null|| y<32){
        y=100
      }
      if (isNaN(height) || height==null|| height<32){
        height=100
      }
      return {x,y,width,height}
    }
  },

  getViewBounds: function () {
    if (webviews.viewFullscreenMap[webviews.selectedId]) {
      log.info('viewFullscreenMap');
      let y=0
      let height=window.innerHeight
      if (isNaN(y) || y==null|| y<32){
        y=32
      }
      if(isNaN(height) || height==null|| height<100){
        height=100
      }
      return {
        x: 0,
        y: y,
        width: window.innerWidth,
        height: height,
      };
    } else {
      log.info("topHeight",topHeight)
      var navbarHeight = topHeight;
      const viewMargins = webviews.viewMargins;
      log.info("viewMargins",viewMargins)
      let y=0 + Math.round(viewMargins[0]) + navbarHeight
      let height=window.innerHeight -Math.round(viewMargins[0] + viewMargins[2]) -navbarHeight
      if (isNaN(y) || y==null|| y<32){
        y=32
      }
      if(isNaN(height) || height==null|| height<100){
        height=100
      }
      return {
        x: 0 + Math.round(viewMargins[3]),
        y: y,
        width: window.innerWidth - Math.round(viewMargins[1] + viewMargins[3]),
        height:height,
      };
    }
  },
  add: function (tabData) {
    let tabid = tabData.id;
    //webviews.state.tabs[webviews.state.tab_value];//
    // var tabData =window.tasklist.task.tabs.get(tabid);

    // needs to be called before the view is created to that its listeners can be registered
    if (tabData.scrollPosition) {
      scrollOnLoad(tabid, tabData.scrollPosition);
    }
    console.log("add")
    if (tabData.muted) {
      setAudioMutedOnCreate(tabid, tabData.muted);
    }
    // setAudioMutedOnCreate(tabid, false);//tabData.muted);
    // if the tab is private, we want to partition it. See http://electron.atom.io/docs/v0.34.0/api/web-view-tag/#partition
    // since tab IDs are unique, we can use them as partition names
    if (tabData.private === true) {
      var partition = tabid.toString(); // options.tabid is a number, which remote.session.fromPartition won't accept. It must be converted to a string first
    }
    var preload_url = myglobal['home'] + '/src/js/preload/preload.js';
    // console.log(preload_url);
    //should be "E:\\multi\\min/dist/preload.js"
    // let boundsString=JSON.stringify({"x":0,"y":48,"width":602,"height":585});
    log.info("brefore send createView");
    ipc.send('createView', {
      id: tabid,
      webPreferencesString: JSON.stringify({
        webPreferences: {
          nodeIntegration: false,
          nodeIntegrationInSubFrames: true,
          scrollBounce: true,
          safeDialogs: true,
          safeDialogsMessage:
            'Prevent this page from creating additional dialogs',
          preload: preload_url,
          contextIsolation: true,
          sandbox: true,
          enableRemoteModule: false,
          allowPopups: false,
          partition:
            partition ||
            (settings.get('disableIsolatedSession')
              ? null
              : 'persist:webcontent'), // TODO remove preference
          enableWebSQL: false,
          autoplayPolicy: 'user-gesture-required',
        },
      }),
      boundsString: JSON.stringify(webviews.getViewBounds()),
      events: webviews.events
        .map((e) => e.event)
        .filter((i, idx, arr) => arr.indexOf(i) === idx),
    });

    if (tabData.url) {
      ipc.send('loadURLInView', {
        id: tabData.id,
        url: urlParser.parse(tabData.url),
      });
    } else if (tabData.private) {
      // workaround for https://github.com/minbrowser/min/issues/872
      ipc.send('loadURLInView', {
        id: tabData.id,
        url: urlParser.parse('min://newtab'),
      });
    }

    webviews.viewList.push(tabid);
  },
  setSelected: function (id, options) {
    console.log("webviews setSelected=========")
    console.log(id, options);
    // options.focus - whether to focus the view. Defaults to true.
    webviews.emitEvent('view-hidden', webviews.selectedId);

    webviews.selectedId = id;

    // create the view if it doesn't already exist
    if (!webviews.viewList.includes(id)) {
      webviews.add({ id: id });
    }

    // if (webviews.placeholderRequests.length > 0) {
    //   // update the placeholder instead of showing the actual view
    //   webviews.requestPlaceholder();
    //   return;
    // }
    let bounds= webviews.getViewBounds()
    // bounds.y=100;
    ipc.send('setView', {
      id: id,
      bounds: bounds,
      focus: !options || options.focus !== false,
    });
    webviews.emitEvent('view-shown', id);

    // forceUpdateDragRegions();
  },
  update: function (id, url) {
    var url1 = urlParser.parse(url);
    // ipc.send('loadURLInView', { id: id, url: urlParser.parse(url) })
    console.log(url);
    ipc.send('loadURLInView', { id: id, url: url1 });
  },
  destroy: function (id) {
    webviews.emitEvent('view-hidden', id);

    if (webviews.viewList.includes(id)) {
      webviews.viewList.splice(webviews.viewList.indexOf(id), 1);
      ipc.send('destroyView', id);
    }
    delete webviews.viewFullscreenMap[id];
    if (webviews.selectedId === id) {
      webviews.selectedId = null;
    }
  },
  releaseFocus: function () {
    ipc.send('focusMainWebContents');
  },
  focus: function () {
    if (webviews.selectedId) {
      ipc.send('focusView', webviews.selectedId);
    }
  },
  resize2: function (height) {
    bounds=webviews.getViewBounds2(height)
    // bounds.y=100
    ipc.send('setBounds', {
      id: webviews.selectedId,
      bounds: bounds
    });
  },
  resize: function (height) {
    bounds=webviews.getViewBounds2(height)
    // bounds.y=100
    if (isNaN(bounds.y)||isNaN(bounds.height)){
      ;
    }
    else{
      ipc.send('setBounds', {
        id: webviews.selectedId,
        bounds: bounds
      });
    }
  },
  goBackIgnoringRedirects: function (id) {
    // special case: the current page is an internal page representing a regular webpage, and the previous page in history is that page (which likely means a redirect happened from the original page to the internal page)
    // probably either an error page (after  a redirect from the original page) or reader view
    // var url =  window.tasklist.task.tabs.get(id).url;

    webviews.callAsync(id, 'goBack');
  },
  /*
  Can be called as
  callAsync(id, method, args, callback) -> invokes method with args, runs callback with (err, result)
  callAsync(id, method, callback) -> invokes method with no args, runs callback with (err, result)
  callAsync(id, property, value, callback) -> sets property to value
  callAsync(id, property, callback) -> reads property, runs callback with (err, result)
   */
  callAsync: function (id, method, argsOrCallback, callback) {
    console.log("callAsync")
    console.log(method)
    console.log(argsOrCallback)
    var args = argsOrCallback;
    var cb = callback;
    if (argsOrCallback instanceof Function && !cb) {
      args = [];
      cb = argsOrCallback;
    }
    if (!(args instanceof Array)) {
      args = [args];
    }
    if (cb) {
      var callId = Math.random();
      webviews.asyncCallbacks[callId] = cb;
    }
    ipc.send('callViewMethod', {
      id: id,
      callId: callId,
      method: method,
      args: args,
    });
  },
};

export default webviews;
